/**
 * Copyright (c) 2009 blurredVision
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
 * associated documentation files (the "Software"), to deal in the Software without restriction, 
 * including without limitation the rights to use, copy, modify, merge, publish, distribute, 
 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is 
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all copies or 
 * substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT 
 * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT 
 * OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
#include "StdAfx.h"
#include "Thread.h"
#include <process.h>

namespace thread {

// Thread function
unsigned int __stdcall threadProc(void* ptr) 
{
	// Call the run function of the IRunnable class
	( (IRunnable*)ptr )->run();

	_endthreadex( 0 );

	return 1;
} 


Thread::Thread(IRunnable *ptr)
:	pRunnableObj(ptr),
	hThread(0)
{
}


Thread::~Thread(void)
{
	kill();
}


void Thread::start()
{
	unsigned int threadID;
	// use the Win32 API here to create a thread
	//hThread = (HANDLE) _beginthread( threadProc, 0, pRunnableObj);
	  hThread = (HANDLE) _beginthreadex( NULL, 0, threadProc, pRunnableObj, 0, &threadID);
}


void Thread::stop()
{
}

void Thread::resume() 
{
}

void Thread::kill()
{
	if (hThread) {
		WaitForSingleObject( hThread, INFINITE);
		CloseHandle( hThread );
		hThread = 0;
	}
}

void Thread::sleep(long milliseconds)
{
	Sleep(milliseconds);
}

const HANDLE& Thread::getHandle() const
{
	return hThread;
}

Mutex::Mutex() 
{
	InitializeCriticalSection(&m_criticalSection);
}

Mutex::~Mutex() 
{
	DeleteCriticalSection(&m_criticalSection);
}

void Mutex::lock() 
{
	EnterCriticalSection(&m_criticalSection);
}

void Mutex::unlock() 
{
	LeaveCriticalSection(&m_criticalSection);
}

Lock::Lock(Mutex &mutex) 
:	m_mutex(mutex), 
	m_locked(true) 
{
    mutex.lock();
}

Lock::~Lock() 
{
	m_mutex.unlock();
}



} // namespace
